package com.mt.vsphere.business.vsphere;

import com.vmware.vim25.*;

import javax.xml.ws.soap.SOAPFaultException;
import java.util.ArrayList;
import java.util.List;

//操作对象帮助
public class VCenterMobHelper {
    /**
     * @功能描述 打印错误信息
     * @param
     * @param sfe
     */
    public static void printSoapFaultException(SOAPFaultException sfe)
    {
        System.out.println("Soap fault: ");
        if (sfe.getFault().hasDetail())
        {
            System.out.println(sfe.getFault().getDetail().getFirstChild().getLocalName());
        }
        if (sfe.getFault().getFaultString() != null)
        {
            System.out.println("Message: " + sfe.getFault().getFaultString());
        }
    }

    public static List<ObjectContent> getResult(VCenterConnectHelper vCenterConnectHelper,ObjectSpec objectSpec, PropertySpec propertySpec) throws Exception {
        PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec();
        propertyFilterSpec.getPropSet().add(propertySpec);
        propertyFilterSpec.getObjectSet().add(objectSpec);

        List<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>(1);
        listpfs.add(propertyFilterSpec);
        return retrievePropertiesAllObjects(vCenterConnectHelper,listpfs);
    }

    //获取某个对象下的属性
    public static List<ObjectContent> getAttrInObj(VCenterConnectHelper helper,ManagedObjectReference obj,String path,String attrType) throws Exception {

        TraversalSpec traversalSpec = new TraversalSpec();
        traversalSpec.setName("VisitObj");
        traversalSpec.setType(obj.getType());
        traversalSpec.setPath(path);
        traversalSpec.setSkip(false);

        ObjectSpec objectSpec = new ObjectSpec();
        objectSpec.setObj(obj);
        objectSpec.setSkip(Boolean.TRUE);
        objectSpec.getSelectSet().add(traversalSpec);

        PropertySpec propertySpec = new PropertySpec();
        propertySpec.setAll(Boolean.FALSE);
        propertySpec.getPathSet().add("name");
        propertySpec.setType(attrType);

        return VCenterMobHelper.getResult(helper,objectSpec,propertySpec);
    }

    //获取某个对象下的属性
    public static List<ObjectContent> getAttrInObj(VCenterConnectHelper helper,ManagedObjectReference obj,String path,String attrType,String...pathset) throws Exception {

        TraversalSpec traversalSpec = new TraversalSpec();
        traversalSpec.setName("VisitObj");
        traversalSpec.setType(obj.getType());
        traversalSpec.setPath(path);
        traversalSpec.setSkip(false);

        ObjectSpec objectSpec = new ObjectSpec();
        objectSpec.setObj(obj);
        objectSpec.setSkip(Boolean.TRUE);
        objectSpec.getSelectSet().add(traversalSpec);

        PropertySpec propertySpec = new PropertySpec();
        propertySpec.setAll(Boolean.FALSE);
        for (String paths:pathset){
            propertySpec.getPathSet().add(paths);
        }
        propertySpec.setType(attrType);

        return VCenterMobHelper.getResult(helper,objectSpec,propertySpec);
    }

    //获取一个参数名字
    public static Object getOneAttrInObj(VCenterConnectHelper helper,ManagedObjectReference obj,String path) throws Exception {
        ObjectSpec objectSpec = new ObjectSpec();
        objectSpec.setObj(obj);
        objectSpec.setSkip(Boolean.FALSE);

        PropertySpec propertySpec = new PropertySpec();
        propertySpec.setAll(Boolean.FALSE);
        propertySpec.getPathSet().add(path);
        propertySpec.setType(obj.getType());

        Object rtnValue = null;
        for (ObjectContent content:VCenterMobHelper.getResult(helper,objectSpec,propertySpec)){
            for (DynamicProperty item : content.getPropSet()){
                if (path.equals(item.getName())){
                    return  item.getVal();
                }
            }
        }
        return rtnValue;
    }
    public static String getObjectNameByMor(VCenterConnectHelper vCenterConnectHelper, ManagedObjectReference mor) throws Exception {
        String objectName = null;
        // 遍历属性规范
        PropertySpec propSpec = new PropertySpec();
        propSpec.setAll(Boolean.FALSE);
        propSpec.getPathSet().add("name");
        propSpec.setType(mor.getType());

        ObjectSpec objSpec = new ObjectSpec();
        objSpec.setObj(mor);
        objSpec.setSkip(Boolean.FALSE);

        // 属性过滤规范
        PropertyFilterSpec spec = new PropertyFilterSpec();
        spec.getPropSet().add(propSpec);
        spec.getObjectSet().add(objSpec);

        ArrayList<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>();
        listpfs.add(spec);

        List<ObjectContent> listobjcont = retrievePropertiesAllObjects(vCenterConnectHelper,listpfs);
        if (listobjcont != null) {
            ObjectContent oc = listobjcont.get(0);
            objectName = (String) oc.getPropSet().get(0).getVal();
        }
        return objectName;
    }
    /**
     * @功能描述 根据属性检索要查询的对象信息
     * @param listpfs 属性过滤器集合
     * @throws Exception
     */
    public static List<ObjectContent> retrievePropertiesAllObjects(VCenterConnectHelper vCenterConnectHelper, List<PropertyFilterSpec> listpfs) throws Exception
    {
        RetrieveOptions propObjectRetrieveOpts = new RetrieveOptions();
        List<ObjectContent> listobjcontent = new ArrayList<ObjectContent>();
        try
        {
            RetrieveResult rslts = vCenterConnectHelper.vimPort.retrievePropertiesEx(vCenterConnectHelper.propCollectorRef, listpfs, propObjectRetrieveOpts);
            if (rslts != null && rslts.getObjects() != null && !rslts.getObjects().isEmpty())
            {
                listobjcontent.addAll(rslts.getObjects());
            }
            String token = null;
            if (rslts != null && rslts.getToken() != null)
            {
                token = rslts.getToken();
            }
            while (token != null && !token.isEmpty())
            {
                rslts = vCenterConnectHelper.vimPort.continueRetrievePropertiesEx(vCenterConnectHelper.propCollectorRef, token);
                token = null;
                if (rslts != null)
                {
                    token = rslts.getToken();
                    if (rslts.getObjects() != null && !rslts.getObjects().isEmpty())
                    {
                        listobjcontent.addAll(rslts.getObjects());
                    }
                }
            }
        }
        catch (SOAPFaultException sfe)
        {
            printSoapFaultException(sfe);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return listobjcontent;
    }

    //收集某个ManagedEntity下的所有属性
    private static RetrieveResult getRetrieveResultObjectWithProperty(VCenterConnectHelper helper,String MorName, String...propertys) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg
    {
        ManagedObjectReference viewMgrRef = helper.serviceContent.getViewManager();
        ManagedObjectReference propColl = helper.serviceContent.getPropertyCollector();

        List<String> vmList = new ArrayList<String>();
        vmList.add(MorName);

        ManagedObjectReference cViewRef = helper.vimPort.createContainerView(viewMgrRef, helper.serviceContent.getRootFolder(), vmList, true);

        ObjectSpec oSpec = new ObjectSpec();
        oSpec.setObj(cViewRef);
        oSpec.setSkip(true);

        TraversalSpec tSpec = new TraversalSpec();
        tSpec.setName("traversalEntities");
        tSpec.setPath("view");
        tSpec.setSkip(false);
        tSpec.setType("ContainerView");

        oSpec.getSelectSet().add(tSpec);

        PropertySpec pSpec = new PropertySpec();
        pSpec.setType(MorName);
        pSpec.getPathSet().add("name");

        PropertySpec pSpecRPr = new PropertySpec();
        pSpecRPr.setType(MorName);
        for (String prp : propertys) {
            pSpecRPr.getPathSet().add(prp);
        }

        PropertyFilterSpec fSpec = new PropertyFilterSpec();
        fSpec.getObjectSet().add(oSpec);
        fSpec.getPropSet().add(pSpec);
        fSpec.getPropSet().add(pSpecRPr);

        List<PropertyFilterSpec> fSpecList = new ArrayList<>();
        fSpecList.add(fSpec);

        RetrieveOptions ro = new RetrieveOptions();
        RetrieveResult props = helper.vimPort.retrievePropertiesEx(propColl, fSpecList, ro);

        return props;
    }
}

